#include "TcpClient.h"

#include <QDebug>
#include <QHostAddress>
#include <QThread>
#include <packet/Packet.h>

TcpClient::TcpClient(QObject* parent)
    : QTcpSocket(parent) {
    // 自动连接在信号发射时被识别为队列连接/信号在主线程发射

    qRegisterMetaType<std::shared_ptr<packge::Packge>>("std::shared_ptr<packge::Packge>");  // 注册新类型
    
    connect(
        this, &TcpClient::SignalConnectToHost, this, [&](const QString& address, quint16 port) {
            // test record# in child thread id 20588
            qDebug("SlotConnectToHost ThreadID:%d", QThread::currentThreadId());
            //
            this->connectToHost(QHostAddress(address), port, QIODevice::ReadWrite);
        },
        Qt::AutoConnection);

    // 连接了TCP服务端
    QObject::connect(this, &QAbstractSocket::connected, this, &TcpClient::onTcpConnected, Qt::DirectConnection);

    // 断开了TCP服务端
    QObject::connect(this, &QAbstractSocket::disconnected, this, &TcpClient::onTcpDisconnected, Qt::DirectConnection);

    // 收到了TCP服务的数据
    QObject::connect(this, &QIODevice::readyRead, this, &TcpClient::onTcpReadyRead, Qt::DirectConnection);

    // 执行数据发送过程
    QObject::connect(this, &TcpClient::SignalSendingData, this, &TcpClient::onSendingData, Qt::QueuedConnection);
}

//
TcpClient::~TcpClient() {
}

// 跨线程转换
void TcpClient::ClientConnectToHost(const QString& address, quint16 port) {
    emit SignalConnectToHost(address, port);
}

// 跨线程转换
void TcpClient::ClientSendingData(const QByteArray& c_btaData) {
    emit SignalSendingData(c_btaData);
}

// 是否在线
bool TcpClient::IsOnline() {
    return isConnected;
}

bool TcpClient::send(packge::Packge& pack) {
    auto data = pack.encode();
    emit SignalSendingData(data);
    return true;
}

void TcpClient::onTcpReadyRead() {
    qDebug() << "onTcpReadyRead";

    auto pack = std::make_shared<packge::Packge>();
    int            len = 0;
    while (bytesAvailable() > 8) {
        len = read(pack->data(), pack->headLenght());

        if (pack->decode()) {
            len = read(pack->body(), pack->bodyLenght());
            qDebug() << "len: " << pack->bodyLenght() << ":" << pack->getBody();

            // 处理数据包
            // processPacket(pack);
            emit signalPacket(pack);
        }
    }
}

void TcpClient::onSocketError(QAbstractSocket::SocketError error) {
    // QMessageBox::warning(nullptr, "错误", errorString());
    qDebug() << "SocketError:" << error << endl
             << errorString();
    disconnectFromHost();
    signalTcpConnected(false);
    isConnected = false;
}

void TcpClient::onTcpConnected() {
    qDebug() << "onTcpConnected";
    signalTcpConnected(true);
    isConnected = true;
}

void TcpClient::onTcpDisconnected() {
    qDebug() << "onTcpDisconnected";
    signalTcpConnected(false);
    isConnected = false;
}

void TcpClient::onSendingData(const QByteArray c_btaData) {
    // test record# in child thread id 20588
    qDebug("SlotSendingData ThreadID:%d", QThread::currentThreadId());
    //
    this->write(c_btaData);
    this->flush();
}
